/**
 * Copyright (c) 2005-2012 https://github.com/zhangkaitao
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 */
package org.mozhu.mboot.core.data.support;

import org.mozhu.mboot.core.data.BaseRepository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.support.JpaEntityInformation;
import org.springframework.data.jpa.repository.support.JpaRepositoryFactory;
import org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean;
import org.springframework.data.repository.core.RepositoryInformation;
import org.springframework.data.repository.core.RepositoryMetadata;
import org.springframework.data.repository.core.support.RepositoryFactorySupport;

import javax.persistence.EntityManager;
import java.io.Serializable;

/**
 * 基础Repostory简单实现 factory bean 请参考 spring-data-jpa-reference [1.4.2. Adding
 * custom behaviour to all repositories]
 * <p>
 * User: Zhang Kaitao
 * <p>
 * Date: 13-5-5 上午11:57
 * <p>
 * Version: 1.0
 */
@SuppressWarnings("unchecked")
public class SimpleBaseRepositoryFactoryBean<R extends JpaRepository<M, ID>, M, ID extends Serializable> extends JpaRepositoryFactoryBean<R, M, ID> {


    public SimpleBaseRepositoryFactoryBean(Class<? extends R> repositoryInterface) {
        super(repositoryInterface);
    }

    @Override
    protected RepositoryFactorySupport createRepositoryFactory(EntityManager entityManager) {
        return new SimpleBaseRepositoryFactory(entityManager);
    }

    class SimpleBaseRepositoryFactory extends JpaRepositoryFactory {

        private EntityManager entityManager;

        public SimpleBaseRepositoryFactory(EntityManager entityManager) {
            super(entityManager);
            this.entityManager = entityManager;
        }

        @Override
        protected Object getTargetRepository(RepositoryInformation information) {
            Class<?> repositoryInterface = information.getRepositoryInterface();
            if (isBaseRepository(repositoryInterface)) {
                JpaEntityInformation<M, ID> entityInformation = getEntityInformation((Class<M>) information.getDomainType());
                SimpleBaseRepository<M, ID> repository = new SimpleBaseRepository<M, ID>(entityInformation, entityManager);
                return repository;
            }
            return super.getTargetRepository(information);
        }

        private boolean isBaseRepository(Class<?> repositoryInterface) {
            return BaseRepository.class.isAssignableFrom(repositoryInterface);
        }

        @Override
        protected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) {
            return SimpleBaseRepository.class;
        }

    }
}
